package com.mti.zhpt.service.impl;

import com.mti.zhpt.dao.CommandReserveDetailMapper;
import com.mti.zhpt.dao.EventSnapShotReserveDetailMapper;
import com.mti.zhpt.model.EventReserveDetailEntity;
import com.mti.zhpt.model.EventSnapShotReserveDetailEntity;
import com.mti.zhpt.service.IEventReserveSnapService;
import com.mti.zhpt.utils.BusinessException;
import com.mti.zhpt.utils.KeyWorker;
import com.mti.zhpt.utils.SnowFlake;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class EventReserveSnapshotServiceImpl implements IEventReserveSnapService {
    private final EventSnapShotReserveDetailMapper detailMapper;
    private final SnowFlake snowFlake;
    private final CommandReserveDetailMapper reserveDetailMapper;

    /**
     * 启动预案
     *
     * @param eventId    事件ID
     * @param reserverId 预案ID
     */
    @Transactional
    @Override
    public Map<String, Object> recordSnapShotDataToDetail(String eventId, String reserverId) {
        if (StringUtils.isEmpty(eventId) || StringUtils.isEmpty(reserverId))
            throw new BusinessException(500, "事件ID或预案ID不能为空");
        List<EventReserveDetailEntity> detailEntityList = reserveDetailMapper.listByReserveId(reserverId);
        if (detailEntityList == null || detailEntityList.isEmpty())
            throw new BusinessException(500, "预案步骤指令为空");
        //保存快照数据
        long count = detailMapper.existByReserveIdAndEventId(eventId, reserverId);
        if(count<=0){
            detailMapper.insertByBatch(detailEntityList.parallelStream().map(item -> {
                EventSnapShotReserveDetailEntity se = new EventSnapShotReserveDetailEntity();
                BeanUtils.copyProperties(item, se);
                se.setEventId(eventId);
                se.setId(snowFlake.nextId());
                se.setReserveDetailId(item.getId());
                se.setCreateTime(LocalDateTime.now());
                return se;
            }).collect(Collectors.toList()));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("unitTask", detailMapper.getStepInfoByEventId(eventId, reserverId,null));
        map.put("personTask", detailMapper.getPersonStepInfoByEventId(eventId, reserverId,null));
        map.put("leaderTask", detailMapper.getLeaderStepInfoByEventId(eventId, reserverId,null));
        map.put("files",reserveDetailMapper.getFilesByReserverId(reserverId).stream().filter(Objects::nonNull).collect(Collectors.toList()));
        return map;
    }

    @Transactional
    @Override
    public void addSnapshotData(EventSnapShotReserveDetailEntity detailEntity) {
        List<EventSnapShotReserveDetailEntity> list = new ArrayList<>();
        detailEntity.setId(KeyWorker.nextId());
        list.add(detailEntity);
        detailMapper.insertByBatch(list);
    }

    @Override
    @Transactional
    public void updateSnapshotData(EventSnapShotReserveDetailEntity detailEntity) {
        if (StringUtils.isEmpty(detailEntity.getId()))
            throw new BusinessException(500, "预案ID不能为空");
        detailMapper.updateById(detailEntity);
    }

    @Override
    public EventSnapShotReserveDetailEntity getEntityById(String id) {
        if (StringUtils.isEmpty(id))
            throw new BusinessException(500, "预案ID不能为空");
        return detailMapper.getById(id);
    }

    @Transactional
    @Override
    public void updateSnapshotDataStatus(String eventReserveId) {
        if (StringUtils.isEmpty(eventReserveId))
            throw new BusinessException(500, "警情预案ID不能为空");
        String[] ids = eventReserveId.split(",");
        detailMapper.batchUpdateSnapshotDataStatus(Arrays.asList(ids));
    }

    @Override
    public Map<String,Map<String, List<Map<Object, Object>>>> getReserveMonitorList(String eventId,String reserveId) {
        Map<String,Map<String, List<Map<Object, Object>>>> map = new HashMap<>();
        //获取实际执行列表
        Map<String, List<Map<Object, Object>>> realMap = new HashMap<>();
        List<Map<Object,Object>> unitTask = detailMapper.getStepInfoByEventId(eventId, reserveId,1);
        List<Map<Object,Object>> personTask = detailMapper.getPersonStepInfoByEventId(eventId, reserveId,1);
        List<Map<Object,Object>> leaderTask = detailMapper.getLeaderStepInfoByEventId(eventId, reserveId,1);
        realMap.put("unitTask", unitTask);
        realMap.put("personTask", personTask);
        realMap.put("leaderTask", leaderTask);
        //获取模板列表
        Map<String, List<Map<Object, Object>>> templateMap = new HashMap<>();
        templateMap.put("unitTask", isUpdateExecute(detailMapper.getTemplateStepInfoByEventId(reserveId),unitTask,"unit"));
        templateMap.put("personTask", isUpdateExecute(detailMapper.getTemplatePersonStepInfoByEventId(reserveId),personTask,"person"));
        templateMap.put("leaderTask", isUpdateExecute(detailMapper.getTemplateLeaderStepInfoByEventId(reserveId),leaderTask,""));
        map.put("template",templateMap);
        map.put("real",realMap);
        return map;
    }

    private List<Map<Object,Object>> isUpdateExecute(List<Map<Object,Object>> resource,List<Map<Object,Object>> compareTo,String type){
        Map<String,Map<Object,Object>> map = new HashMap<>();
        Map<String,Map<Object,Object>> resourceMap = new HashMap<>();
        resource.parallelStream().filter(item->item.containsKey("id") && item.get("id")!=null).forEach(item->resourceMap.put(item.getOrDefault("id","").toString(),item));
        compareTo.parallelStream().filter(item->!resourceMap.containsKey(item.get("reservedetailid"))).forEach(item->item.put("reservedetailid",null));
        compareTo.parallelStream().filter(item->item.containsKey("reservedetailid") && item.get("reservedetailid")!=null).forEach(item->map.put(item.getOrDefault("reservedetailid","").toString(),item));
        return resource
            .parallelStream().peek(r->{
                boolean flag = false;
                r.put("status","0");
                Map<Object,Object> compareItem = map.get(r.getOrDefault("id","").toString());
                if(compareItem!=null && !compareItem.isEmpty()){
                    r.put("status",compareItem.getOrDefault("status","").toString());
                    switch (type){
                        case "unit":{
                            /**
                             * 只能更改remark、dispatchNumber、reverseNumber
                             */
                            Object remark = r.get("remark");
                            Object dispatchNumber = r.get("dispatch_number");
                            Object reserveNumber = r.get("reserve_number");
                            if(remark!=null && !remark.toString().equalsIgnoreCase(compareItem.get("remark")!=null?compareItem.get("remark").toString():"")){
                                flag = true;
                            }
                            if(dispatchNumber!=null && !dispatchNumber.toString().equalsIgnoreCase(compareItem.get("dispatch_number")!=null?compareItem.get("dispatch_number").toString():"")){
                                flag = true;
                            }
                            if(reserveNumber!=null && !reserveNumber.toString().equalsIgnoreCase(compareItem.get("reserve_number")!=null?compareItem.get("reserve_number").toString():"")){
                                flag = true;
                            }
                        }break;
                        /**
                         * 只能更改remark
                         */
                        case "person":{
                            Object remark = r.get("remark");
                            if(remark!=null && !remark.toString().equalsIgnoreCase(compareItem.get("remark")!=null?compareItem.get("remark").toString():"")){
                                flag = true;
                            }
                        }break;
                    }
                }
                r.put("isUpdateExecute",flag);
                }).collect(Collectors.toList());
    }
}
